#include "n32g031.h"
#include "stdint.h"
#include "stdio.h"
#include "DevicesDelay.h"
#include "DevicesADC.h"

static uint16_t st_usADC1DmaDatas[ADC1_SAMPLING_NUMBER][ADC1_SAMPLING_CHANNEL] = {0};


void vADCInit(void)
{
    ADC_InitType ADC_InitStructure = {0};
    DMA_InitType DMA_InitStructure = {0};
    GPIO_InitType GPIO_InitStructure = {0};

    /* Enable DMA clocks */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
    /* Enable GPIOC clocks */
    RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOA | RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_AFIO, ENABLE);
    /* Enable ADC clocks */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC, ENABLE);

#if 1
    /* RCC_ADCHCLK_DIV16*/
    ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB, RCC_ADCHCLK_DIV16);
    RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSI, RCC_ADC1MCLK_DIV8);

#else
    /* RCC_ADCPLLCLK_DIV256 */
    ADC_ConfigClk(ADC_CTRL3_CKMOD_PLL, RCC_ADCPLLCLK_DIV256);
    RCC_ConfigAdcPllClk(RCC_ADCPLLCLK_DIV256, ENABLE);

#endif


    GPIO_InitStruct(&GPIO_InitStructure);
    /* Configure GPIOx as analog input -------------------------*/
    GPIO_InitStructure.Pin       = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_MODE_ANALOG;
    GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.Pin       = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
    GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);


    ADC_EnableTempSensorVrefint(ENABLE);
    ADC_EnableTempSensor(ENABLE);
    ADC_EnableVrefint(ENABLE);


    /* ADC configuration ------------------------------------------------------*/
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = ENABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_NONE;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = ADC1_SAMPLING_CHANNEL;
    ADC_Init(ADC, &ADC_InitStructure);

    /* ADC regular channel1 configuration */
    ADC_ConfigRegularChannel(ADC, ADC_CH_3_PA3,  ADC_DMA_CHANNEL_TEMPERATURE + 1,    ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_4_PA4,  ADC_DMA_CHANNEL_HOST_HOLD + 1,      ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_5_PA5,  ADC_DMA_CHANNEL_DUST_BAG + 1,       ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_7_PA7,  ADC_DMA_CHANNEL_MOTO + 1,           ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_8_PB0,  ADC_DMA_CHANNEL_BLOWER + 1,         ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_9_PB1,  ADC_DMA_CHANNEL_CHARGE_STATE + 1,   ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_10_PB2, ADC_DMA_CHANNEL_CHARGE_CURRENT + 1, ADC_SAMPLE_TIME);

    ADC_ConfigRegularChannel(ADC, ADC_CH_TEMP_SENSOR,   ADC_DMA_CHANNEL_TEMP_SENSOR + 1,    ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_VREFINT,       ADC_DMA_CHANNEL_VREFINT + 1,        ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_VREFP,         ADC_DMA_CHANNEL_VREFP + 1,          ADC_SAMPLE_TIME);
    ADC_ConfigRegularChannel(ADC, ADC_CH_VDDA,          ADC_DMA_CHANNEL_VDDA + 1,           ADC_SAMPLE_TIME);


    /* DMA channel1 configuration ----------------------------------------------*/
    DMA_DeInit(DMA_CH1);
    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC->DAT;
    DMA_InitStructure.MemAddr        = (uint32_t)&st_usADC1DmaDatas;
    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize        = ADC1_SAMPLING_NUMBER * ADC1_SAMPLING_CHANNEL;
    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.CircularMode   = DMA_MODE_CIRCULAR;
    DMA_InitStructure.Priority       = DMA_PRIORITY_HIGH;
    DMA_InitStructure.Mem2Mem        = DMA_M2M_DISABLE;
    DMA_Init(DMA_CH1, &DMA_InitStructure);
    DMA_RequestRemap(DMA_REMAP_ADC, DMA, DMA_CH1, ENABLE);

    /* Enable DMA channel1 */
    DMA_EnableChannel(DMA_CH1, ENABLE);

    /* Enable ADC DMA */
    ADC_EnableDMA(ADC, ENABLE);

    /* Enable ADC */
    ADC_Enable(ADC, ENABLE);

    /*wait ADC is ready to use*/
    while(!ADC_GetFlagStatusNew(ADC, ADC_FLAG_RDY));
    /*wait ADC is powered on*/
    while(ADC_GetFlagStatusNew(ADC, ADC_FLAG_PD_RDY));

    vDelayMs(50);

    /* Start ADC Software Conversion */
    ADC_EnableSoftwareStartConv(ADC, ENABLE);
}

/*!
    \brief      ADC dma channel
    \param[in]  none
    \param[out] none
    \retval     none
*/
float fADCGetValue(uint8_t ucChannel)
{
    uint32_t uiValueSum = 0;
    uint16_t *pDatasHand = (uint16_t *)st_usADC1DmaDatas;
    uint16_t usValueNow = 0, usValueMax = 0, usValueMin = 0xFFFF, i = 0;

    if(ucChannel >= ADC1_SAMPLING_CHANNEL)
        return 0.0f;

    pDatasHand += ucChannel;

    for(i = 0; i < ADC1_SAMPLING_NUMBER; ++i)
    {
        usValueNow  = *pDatasHand;
        uiValueSum += usValueNow;

        pDatasHand += ADC1_SAMPLING_CHANNEL;

        /* 找到最大与最小值 */
        usValueMax = (usValueMax < usValueNow) ? usValueNow : usValueMax;
        usValueMin = (usValueMin > usValueNow) ? usValueNow : usValueMin;
    }

    uiValueSum -= usValueMax + usValueMin;

   return ((float)uiValueSum / (ADC1_SAMPLING_NUMBER - 2) * (3300.0f / 4095.0f));
}
